package com.slz.crm.server.init;

import com.slz.crm.common.enumeration.PermissionOperates;
import com.slz.crm.pojo.entity.PermissionsEntity;
import com.slz.crm.server.mapper.PermissionsMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

import static com.slz.crm.server.constant.PermissonConstant.*;

@Component
@Slf4j
public class PermissionSyncRunner implements CommandLineRunner {

    @Resource
    private PermissionsMapper permissionsMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void run(String... args) throws Exception {
        log.info("开始权限同步...");

        // 1. 获取数据库中所有现有权限
        List<PermissionsEntity> existingPermissions = permissionsMapper.selectList(null);
        Map<Long, PermissionsEntity> existingPermissionMap = existingPermissions.stream()
                .collect(Collectors.toMap(PermissionsEntity::getId, perm -> perm));

        // 2. 构建所有需要的权限
        List<PermissionsEntity> allRequiredPermissions = buildAllRequiredPermissions();

        // 3. 批量处理：新增、更新、删除
        processPermissions(allRequiredPermissions, existingPermissionMap);

        log.info("权限同步完成，共处理 {} 个权限", allRequiredPermissions.size());
    }

    /**
     * 构建所有需要的权限实体
     */
    private List<PermissionsEntity> buildAllRequiredPermissions() {
        List<PermissionsEntity> allPermissions = new ArrayList<>();

        // 使用反射统一处理所有枚举类型
        processEnumPermissions(allPermissions, PermissionOperates.CustomerOperate.class, CUSTOMER_PREFIX);
        processEnumPermissions(allPermissions, PermissionOperates.SalesOperate.class, SALES_PREFIX);
        processEnumPermissions(allPermissions, PermissionOperates.FinanceOperate.class, FINANCE_PREFIX);
        processEnumPermissions(allPermissions, PermissionOperates.TaskOperate.class, TASK_PREFIX);
        processEnumPermissions(allPermissions, PermissionOperates.ReportOperate.class, REPORT_PREFIX);
        processEnumPermissions(allPermissions, PermissionOperates.SystemOperate.class, SYSTEM_PREFIX);
        processEnumPermissions(allPermissions, PermissionOperates.ProjectOperate.class, PROJECT_PREFIX);

        return allPermissions;
    }

    /**
     * 通过反射统一处理枚举权限
     */
    @SuppressWarnings("unchecked")
    private <T extends Enum<T> & PermissionOperates.Operation> void processEnumPermissions(
            List<PermissionsEntity> allPermissions,
            Class<T> enumClass,
            String prefix) {

        try {
            // 获取枚举类的values方法
            Method valuesMethod = enumClass.getMethod("values");
            T[] enumValues = (T[]) valuesMethod.invoke(null);

            for (T operation : enumValues) {
                PermissionsEntity perm = new PermissionsEntity();
                perm.setId(operation.getId());
                perm.setPermissionsName(prefix + operation.name());
                perm.setPermissionsDesc(operation.getDescription());
                allPermissions.add(perm);
            }
        } catch (Exception e) {
            log.error("处理枚举权限时发生错误: {}", enumClass.getSimpleName(), e);
        }
    }

    /**
     * 批量处理权限：新增、更新、删除
     */
    private void processPermissions(
            List<PermissionsEntity> requiredPermissions,
            Map<Long, PermissionsEntity> existingPermissionMap) {

        List<PermissionsEntity> toInsert = new ArrayList<>();
        List<PermissionsEntity> toUpdate = new ArrayList<>();
        Set<Long> requiredIds = requiredPermissions.stream()
                .map(PermissionsEntity::getId)
                .collect(Collectors.toSet());

        // 1. 处理需要新增和更新的权限
        for (PermissionsEntity requiredPerm : requiredPermissions) {
            PermissionsEntity existingPerm = existingPermissionMap.get(requiredPerm.getId());

            if (existingPerm == null) {
                // 新权限：添加到新增列表
                toInsert.add(requiredPerm);
                log.debug("新增权限: {} - {}", requiredPerm.getPermissionsName(), requiredPerm.getPermissionsDesc());
            } else {
                // 已有权限：检查是否需要更新
                if (!Objects.equals(existingPerm.getPermissionsDesc(), requiredPerm.getPermissionsDesc()) ||
                    !Objects.equals(existingPerm.getPermissionsName(), requiredPerm.getPermissionsName())) {

                    existingPerm.setPermissionsDesc(requiredPerm.getPermissionsDesc());
                    existingPerm.setPermissionsName(requiredPerm.getPermissionsName());
                    toUpdate.add(existingPerm);
                    log.debug("更新权限: {} - {}", requiredPerm.getPermissionsName(), requiredPerm.getPermissionsDesc());
                }
            }
        }

        // 3. 批量执行数据库操作
        if (!toInsert.isEmpty()) {
            batchInsertPermissions(toInsert);
            log.info("新增权限数量: {}", toInsert.size());
        }

        if (!toUpdate.isEmpty()) {
            toUpdate.forEach(permissionsMapper::updateById);
            log.info("更新权限数量: {}", toUpdate.size());
        }

    }

    /**
     * 批量插入权限，使用自定义的insertANDID方法
     */
    private void batchInsertPermissions(List<PermissionsEntity> permissions) {
        for (PermissionsEntity perm : permissions) {
            permissionsMapper.insertANDID(perm);
        }
    }
}
